昨天我們學會了把文字轉成 Embeddings 向量,並比較不同句子之間的相似度。
今天要更進一步 —— 用這個方法來建立一個 FAQ 知識庫,讓 AI 可以從中找到最相關的答案。
想像一下,如果公司有一堆文件或常見問題, 我們就可以把它們「轉成向量」存起來。
當使用者提問時:
這就是簡單版的 RAG
先寫一個小小 FAQ:
faq_data = [
{"q": "你們的服務時間是?", "a": "我們的客服時間是週一到週五,早上 9 點到下午 6 點。"},
{"q": "如何重設密碼?", "a": "請到登入頁面點選『忘記密碼』,系統會寄重設連結到你的信箱。"},
{"q": "支援哪些付款方式?", "a": "我們支援信用卡、ATM 轉帳,以及超商付款。"},
{"q": "有提供發票嗎?", "a": "是的,所有訂單都會開立電子發票並寄送到你的信箱。"},
]
再來把 FAQ 問題轉成向量
import os
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
def get_embedding(text):
return client.embeddings.create(
model="text-embedding-3-small",
input=text
).data[0].embedding
for item in faq_data:
item["embedding"] = get_embedding(item["q"])
最後我們來寫一個搜尋函數
from numpy import dot
from numpy.linalg import norm
def cosine_similarity(a, b):
return dot(a, b) / (norm(a) * norm(b))
def search_faq(user_question):
q_embedding = get_embedding(user_question)
scores = []
for item in faq_data:
score = cosine_similarity(q_embedding, item["embedding"])
scores.append((score, item))
scores.sort(key=lambda x: x[0], reverse=True)
return scores[0][1]["a"] # 回傳最相關的答案
可以看到雖然提問方式不同,但 AI 還是找到正確答案
程式主要的重點在於把 FAQ 問題轉成向量、使用 cosine similarity 比較相似度以及選擇分數最高的答案。
這就是一個最簡單的 FAQ 檢索系統。
今天我們成功用 Embeddings 建立 FAQ 知識庫,
讓 AI 能回答不同問法但同樣意思的問題。
明天我們要進一步做一個互動式 QA 系統,輸入問題讓AI自動找最接近的答案並回覆!